﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Learn_operators
{
    class Program
    {
        static void Main(string[] args)
        {
            //int x = int.MinValue;
            //int y = -x;  // 取反，二进制按位取反后+1
            //Console.WriteLine(y);
            //string xStr = Convert.ToString(x, 2).PadLeft(32, '0');
            //Console.WriteLine(xStr);

            //int x = 100;  // C#中int型是补码
            //int y = -(-x);
            //Console.WriteLine(y);

            //int x = 12345678;
            //int y = ~x;   // 按位取反，求反码
            //Console.WriteLine(y);
            //string xStr = Convert.ToString(x, 2).PadLeft(32, '0');
            //string yStr = Convert.ToString(y, 2).PadLeft(32, '0');
            //Console.WriteLine(xStr);
            //Console.WriteLine(yStr);

            //Student stu = new Student(null);
            //Console.WriteLine(stu.Name);


            /*
             隐式（implicit）类型转换
                不丢失精度的转换
                子类向父类的转换
                装箱
             */
            //int x = int.MaxValue;
            //long y = x;
            //Teacher p1 = new Teacher();  // p1继承到 eat(), think(), teach()
            //Human h = p1;                // h只能调用 eat(), think()   子类向父类的隐式类型转换


            /*
            显式（explicit）类型转换
                有可能丢失精度（甚至发生错误）的转换，即 cast
                拆箱
                使用Convert类
                ToString方法与各数据类型的Parse/TryParse方法
             */
            //Console.WriteLine(ushort.MaxValue);
            //uint x = 65536;
            //ushort y = (ushort)x;  // 显示类型转换
            //Console.WriteLine(y);


            /*
            自定义类型转换操作符
             */
            // Convert.ToChar();   // Convert转换数据类型
            //string a = "1";
            //string b = "2";
            //double x = System.Convert.ToDouble(a);
            //double y = System.Convert.ToDouble(b);
            //double z = x + y;
            //Console.WriteLine(z);

            {
                Stone stone = new Stone();
                stone.Age = 5000;
                Monkey wukongSun = (Monkey)stone;
                Console.WriteLine(wukongSun.Age);
            }


            {
                double x = (double)5 / 4;   // 1.25
                Console.WriteLine(x);
            }


            {
                double y = (double)(5 / 4);  // 1
                Console.WriteLine(y);
            }

            {
                var x = 3.0 + 4;
                Console.WriteLine(x.GetType().Name);  // double
                Console.WriteLine(x);  // 7
            }

            {
                int x = 7;
                int y = x << 1;   // 二进制左移一位，负数补码也只左移1位,相当于乘2
                string strX = Convert.ToString(x, 2).PadLeft(32, '0');
                string strY = Convert.ToString(y, 2).PadLeft(32, '0');
                Console.WriteLine("x:" + x);
                Console.WriteLine("y:" + y);
                Console.WriteLine(strX);
                Console.WriteLine(strY);
            }

            {
                int x = 7;
                int y = x >> 2;   // 补码算术右移
                string strX = Convert.ToString(x, 2).PadLeft(32, '0');
                string strY = Convert.ToString(y, 2).PadLeft(32, '0');
                Console.WriteLine("x:" + x);
                Console.WriteLine("y:" + y);
                Console.WriteLine(strX);
                Console.WriteLine(strY);
            }

            {
                Teacher t = new Teacher();
                var result = t is Human;
                Console.WriteLine(result.GetType().FullName);
                Console.WriteLine(result);   // true
            }

            {
                object obj = "Hello, world!";
                string str = obj as string;  // as 尝试类型转换

                if (str != null)
                {
                    Console.WriteLine($"转换成功：{str}");
                }
                else
                {
                    Console.WriteLine("转换失败");
                }
            }

            {
                int x = 7;
                int y = 28;
                int z = x & y;  // 按位与运算，两个都是1才是1
                string strX = Convert.ToString(x, 2).PadLeft(32, '0');
                string strY = Convert.ToString(y, 2).PadLeft(32, '0');
                string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
                Console.WriteLine(strX);  // 00000000000000000000000000000111
                Console.WriteLine(strY);  // 00000000000000000000000000011100
                Console.WriteLine(strZ);  // 00000000000000000000000000000100
            }

            {
                int x = 7;
                int y = 28;
                int z = x | y;  // 按位或运算，两个都是0才是0
                string strX = Convert.ToString(x, 2).PadLeft(32, '0');
                string strY = Convert.ToString(y, 2).PadLeft(32, '0');
                string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
                Console.WriteLine(strX);  // 00000000000000000000000000000111
                Console.WriteLine(strY);  // 00000000000000000000000000011100
                Console.WriteLine(strZ);  // 00000000000000000000000000011111
            }

            {
                int x = 7;
                int y = 28;
                int z = x ^ y;  // 按位异或运算，不一样是1，一样是0
                string strX = Convert.ToString(x, 2).PadLeft(32, '0');
                string strY = Convert.ToString(y, 2).PadLeft(32, '0');
                string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
                Console.WriteLine(strX);  // 00000000000000000000000000000111
                Console.WriteLine(strY);  // 00000000000000000000000000011100
                Console.WriteLine(strZ);  // 00000000000000000000000000011011
            }

            {
                int a = 3;
                if(a++ > 3)
                {
                    Console.WriteLine(a);
                }
                Console.WriteLine(a);  // a = 4
            }

            {
                int a = 3;
                int b = 4;
                if(b == 4 || a++ > 2)
                {
                    Console.WriteLine(a);  // 3
                }
                Console.WriteLine(a);  // 3

                if(b == 4 && a++ > 2)
                {
                    Console.WriteLine(a);  // 4
                }
                Console.WriteLine(a);  // 4
            }

            {
                int? x = null;
                int y = x ?? 1; // 如果 x 是 null，则 y 取 1
                Console.WriteLine(y); // 输出 1
            }

            {
                int? x = 10;
                int y = x ?? -1; // x 有值，则 y = x，否则 y = -1
                Console.WriteLine(y); // 输出 10

                // string name = null;
                // string displayName = name ?? "Unknown";
                // Console.WriteLine(displayName); // 输出 "Unknown"

                // int? x = null;
                // x ??= 100; // 如果 x 为 null，则赋值 100
                // Console.WriteLine(x); // 输出 100

            }
        }
    }

    class Student
    {
        public string Name;
        public Student(string initName)
        {
            if (!string.IsNullOrEmpty(initName)) 
            {
                this.Name = initName;
            }
            else
            {
                //throw new ArgumentException("initName cannot be null or empty.");
                Console.WriteLine("initName cannot be null or empty.");
            }
        }
    }

    class Animal
    {
        public void Eat()
        {
            Console.WriteLine("Eating……");
        }
    }

    class Human: Animal
    {
        public void Think()
        {
            Console.WriteLine("Thinking……");
        }
    }

    class Teacher: Human
    {
        public void Teach()
        {
            Console.WriteLine("Teaching……");
        }
    }

    class Stone
    {
        public int Age;

        public static explicit operator Monkey(Stone stone)
        {
            Monkey m = new Monkey();
            m.Age = stone.Age / 500;
            return m;
        }
    }

    class Monkey
    {
        public int Age;
    }
}
